/*+***********************************************************************************
 Filename: 02_verilog_step03\src\top.v
 Description: Examples for demo the verilog in modeling the sequencial logic circuit,
    on the TangNano9k module.

 Modification:
   2022.10.02 Creation   H.Zheng

Copyright (C) 2022  Zheng Hui (hzheng@gzhu.edu.cn)

License: MulanPSL-2.0

***********************************************************************************-*/

module top
(
    input wire [1:0] button,
    input wire sys_clk,
    output wire [5:0] led
);

/**
 * NOTE: comment to select different sample
 */

//sample 1: toggle led0 via button0 and reset via button1.

/*
reg q;
wire clk;
wire reset_n;
wire d;


always @(negedge clk or negedge reset_n) begin
    if (~reset_n) begin
	    q <= 1;
	end
	else begin
	    q <= ~q;
	end
end

assign clk = button[0];
assign reset_n = button[1];

assign led[0] = q;

assign led[5:1] = {5{1'b1}};

*/

//sample 2: a sample counter, count via button0 and reset via button1.

 /*
reg [5:0] q;
wire clk;
wire reset_n;
wire d;

always @(negedge clk or negedge reset_n) begin
    if (~reset_n) begin
	    q <= 0;
	end
	else begin
	    q <= q + 1'b1;
	end
end

assign clk = button[0];
assign reset_n = button[1];

assign led = ~q;

 */

//sample 3: a 1s timer.

 /*

reg [6:0] counter1;
wire reset_n;
reg clk_206T0;

always @(posedge sys_clk or negedge reset_n) begin
    if (~reset_n) begin
	    counter1 <= 0;
        clk_206T0 <=0;
	end
	else begin
        if (counter1 >= 102) begin
            counter1 <= 0;
            clk_206T0 <= ~clk_206T0;
        end
        else begin
	        counter1 <= counter1 + 1'b1;
        end    
	end
end

reg [22:0] counter2;

always @(posedge clk_206T0 or negedge reset_n) begin
    if (~reset_n) begin
	    counter2 <= 0;
	end
	else begin
	    counter2 <= counter2 + 1'b1;
	end
end

assign reset_n = button[1];

assign led = ~counter2[22:17];
 */


//sample 4: breathing led.

 /*

//use 1s counter to generate the pulse width compare value,
//changed from 0 to 255 with 2s.

reg [6:0] counter1;
wire reset_n;
reg clk_206T0;

always @(posedge sys_clk or negedge reset_n) begin
    if (~reset_n) begin
	    counter1 <= 0;
        clk_206T0 <=0;
	end
	else begin
        if (counter1 >= 102) begin
            counter1 <= 0;
            clk_206T0 <= ~clk_206T0;
        end
        else begin
	        counter1 <= counter1 + 1'b1;
        end    
	end
end

reg [22:0] counter2;

always @(posedge clk_206T0 or negedge reset_n) begin
    if (~reset_n) begin
	    counter2 <= 0;
	end
	else begin
	    counter2 <= counter2 + 1'b1;
	end
end

wire [7:0] pulse_width = counter2[17:10];

//pwm generater
reg [7:0] pwm_counter;
reg pwm_output;

always @(posedge clk_206T0 or negedge reset_n) begin
    if (~reset_n) begin
	    pwm_counter <= 0;
        pwm_output <= 0;
	end
	else begin
	    pwm_counter <= pwm_counter + 1'b1;
        if (pwm_counter < pulse_width) begin
            pwm_output <= 1;
        end
        else begin
            pwm_output <= 0;
        end
	end
end

//assoiciate pins
assign reset_n = button[1];
assign led[0] = ~counter2[17];
assign led[5:1] = {5{~pwm_output}};

 */

//sample 5: marquee led.

// /*

//use 1s counter trigger the shift.

reg [6:0] counter1;
wire reset_n;
reg clk_206T0;

always @(posedge sys_clk or negedge reset_n) begin
    if (~reset_n) begin
	    counter1 <= 0;
        clk_206T0 <=0;
	end
	else begin
        if (counter1 >= 102) begin
            counter1 <= 0;
            clk_206T0 <= ~clk_206T0;
        end
        else begin
	        counter1 <= counter1 + 1'b1;
        end    
	end
end

reg [16:0] counter2;

always @(posedge clk_206T0 or negedge reset_n) begin
    if (~reset_n) begin
	    counter2 <= 0;
	end
	else begin
	    counter2 <= counter2 + 1'b1;
	end
end

wire clk_1s = counter2[16];

//round shift
reg [5:0] led_value;

always @(posedge clk_1s or negedge reset_n) begin
    if (~reset_n) begin
	    led_value <= 6'b000011;  //initial pattern of leds
	end
	else begin
	    led_value <= {led_value[4:0], led_value[5]};
	end
end

//assoiciate pins
assign reset_n = button[1];
assign led = ~led_value;

// */


endmodule